//
//  NetRequest.m
//  DDKelai
//
//  Created by Admin on 16/1/6.
//  Copyright (c) 2016年 chenwenhao. All rights reserved.
//

#import "NetRequest.h"
#import "AutoLoginManager.h"

@implementation NetRequest

/**
 @brief 单例
 @discussion 获取该类单例进行操作
 @return 返回类实例
 */
+ (NetRequest*)sharedInstance
{
    static dispatch_once_t onceBasicToken;
    
    static NetRequest *BasicRequest = nil;
    
    dispatch_once(&onceBasicToken, ^{
        BasicRequest = [[NetRequest alloc] init];
    });
    return BasicRequest;
}

/**
 @brief 通过baseURL产生单例
 @discussion 获取该类单例进行操作
 @return 返回类实例
 */
+ (NetRequest*)sharedInstanceWithBaseURL:(NSString *)baseURL
{
    static dispatch_once_t onceToken;
    static NetRequest *netRequest = nil;
    dispatch_once(&onceToken, ^{
        netRequest = [[NetRequest alloc] initNetRequestWithBaseURL:baseURL];
    });
    return netRequest;
}

/**
 @brief 初始化网络请求
 @param baseURL 网络请求的基础URL
 */
- (id)initNetRequestWithBaseURL:(NSString *)baseURL
{
    self = [super init];
    if (self) {
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
        if ([baseURL containsString:@"https"]) {
            _manager.securityPolicy = [NetRequest customSecurityPolicy];
        }
    }
    return self;
}


/**
 @brief 初始化网络请求
 @param 预设值
 */
- (id)init
{
    self = [super init];
    if (self) {
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:baseRequestUrl]];
        if ([baseRequestUrl containsString:@"https"]) {
            _manager.securityPolicy = [NetRequest customSecurityPolicy];
        }
    }
    return self;
}

/**
 @brief 通过post方式请求数据
 @param urlScheme 请求数据的接口
 @param paramsDict 请求参数的NSDictionary
 @param interfaceVersion 接口版本号
 @param contentType 接口版本号
 @param success 请求数据成功的回调block
 @param fail 请求数据失败的回调block
 */
- (NSURLSessionDataTask *)postDataFromURLScheme:(NSString *)urlScheme
                               paramsDictionary:(id)paramsDict
                               interfaceVersion:(NSString *)interfaceVersion
                                    contentType:(NSString *)contentType
                                        success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                                           fail:(void (^)(RequestError *errMsg))fail
{
    
    if (interfaceVersion.length)
    {
        urlScheme = [NSString stringWithFormat:@"/api/%@%@",interfaceVersion,urlScheme];
    }
    else
    {
//        if ([urlScheme rangeOfString:kDAQUrl].location == NSNotFound) {
//            urlScheme = [@"/api" stringByAppendingString:urlScheme];
//        }
    }
    
    [self addHttpRequestHeader:contentType rawData:NO params:paramsDict];
    
    NSURLSessionDataTask *dataTask = [self postDataFromURLScheme:urlScheme paramsDictionary:paramsDict success:success fail:fail];
    
    return dataTask;
    
}


/**
 @brief 通过post方式请求数据
 @param urlScheme 请求数据的接口
 @param paramsDict 请求参数的NSDictionary
 @param interfaceVersion 接口版本号
 @param success 请求数据成功的回调block
 @param fail 请求数据失败的回调block
 */
- (NSURLSessionDataTask *)postDataFromURLScheme:(NSString *)urlScheme
             paramsDictionary:(id)paramsDict
             interfaceVersion:(NSString *)interfaceVersion
                      success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                         fail:(void (^)(RequestError *errMsg))fail
{
    
    NSURLSessionDataTask *dataTask = [self postDataFromURLScheme:urlScheme paramsDictionary:paramsDict interfaceVersion:interfaceVersion contentType:nil success:success fail:fail];
    
    return dataTask;
}

/**
 @brief 通过post方式请求数据
 @param urlScheme 请求数据的接口
 @param paramsDict 请求参数的NSDictionary
 @param success 请求数据成功的回调block
 @param fail 请求数据失败的回调block
 */
- (NSURLSessionDataTask *)postDataFromURLScheme:(NSString *)urlScheme
             paramsDictionary:(id)paramsDict
                      success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                         fail:(void (^)(RequestError *errMsg))fail
{
    
    NSURLSessionDataTask *dataTask = [_manager POST:urlScheme parameters:paramsDict progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
      if ([responseObject isKindOfClass:[NSDictionary class]])
        {
            NSDictionary *dict = (NSDictionary *)responseObject;
            NSString *isSuccess = [NSString stringWithFormat:@"%@",[dict objectForKey:@"executeStatus"]];

            if ([isSuccess isEqualToString:@"0"])
            {
                RequestError *error = [RequestError initWithCode:isSuccess andErrorMsg:kSuccessMessage];
                success([dict objectForKey:@"values"], YES, error);
            }
            else if ([isSuccess isEqualToString:@"3"] || [isSuccess isEqualToString:@"4"])
            {
                RequestError *error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                //屏蔽，先自动登录
//                success(nil, NO, error);
                //非登录session超时,才自动登录,待测试
                if (![urlScheme isEqualToString:kLoginAppUrl]) {
                    [AutoLoginManager autoLogin:urlScheme paramsDictionary:paramsDict success:^(id data, BOOL isSuccess, RequestError *msg) {
                        if (success) {
                            success(data,isSuccess,msg);
                        }
                    } fail:^(RequestError *errMsg) {
                        if (fail) {
                            fail(errMsg);
                        }
                    }];
                }
              
            
                //NSURLSessionDataTask *dataTask = [[UserManager getInstance] logout];
                
               /* if (dataTask) {
                    [SVProgressHUD showErrorWithStatus:[isSuccess isEqualToString:@"3"]?@"登录失效，请重新登录！":@"用户账号已删除！" duration:2.0];
                }*/
                
            }
            else if ([isSuccess isEqualToString:@"10"] || [isSuccess isEqualToString:@"11"])
            {
                RequestError *error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                
                success(nil, NO, error);

               /* [SVProgressHUD showErrorWithStatus:[isSuccess isEqualToString:@"10"]?@"缺少签名字段":@"签名错误" duration:2.0];*/
            }
            else
            {
                RequestError *error = nil;
                
                if ([(NSString *)[dict objectForKey:@"errorCode"] length]) {
                    error = [RequestError initWithCode:[dict objectForKey:@"errorCode"] andErrorMsg:[dict objectForKey:@"errorMsg"]];
                }
                else
                {
                    error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                }
                
                success(nil, NO, error);
            }
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"-- %@", error.description);
        RequestError *errorMsg = [RequestError initWithCode:[NSString stringWithFormat:@"%@",[NSNumber numberWithInteger:error.code]] andErrorMsg:kFailMessage];
        fail(errorMsg);
    }];
    
    return dataTask;
}

/*
 @brief 通过get方式请求数据
 @param urlScheme 请求数据的接口
 @param paramsDict 请求参数的NSDictionary
 @param success 请求数据成功的回调block
 @param fail 请求数据失败的回调block
 */
- (NSURLSessionDataTask *)getDataFromURLScheme:(NSString *)urlScheme
            paramsDictionary:(id)paramsDict
                     success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                        fail:(void (^)(RequestError *errMsg))fail
{
    NSURLSessionDataTask *dataTask = [_manager GET:urlScheme parameters:paramsDict progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if ([responseObject isKindOfClass:[NSDictionary class]]) {
            
            NSDictionary *dict = (NSDictionary *)responseObject;
            NSString *isSuccess = [NSString stringWithFormat:@"%@",[dict objectForKey:@"executeStatus"]];
            
            if ([isSuccess isEqualToString:@"0"]) {
                
                RequestError *error = [RequestError initWithCode:isSuccess andErrorMsg:kSuccessMessage];
                success([dict objectForKey:@"values"], YES, error);
            }
            else if ([isSuccess isEqualToString:@"3"] || [isSuccess isEqualToString:@"4"])
            {
                RequestError *error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                
                success(nil, NO, error);
                /*
                NSURLSessionDataTask *dataTask = [[UserManager getInstance] logout];
                
                if (dataTask) {
                    [SVProgressHUD showErrorWithStatus:[isSuccess isEqualToString:@"3"]?@"登录失效，请重新登录！":@"用户账号已删除！" duration:2.0];
                }*/
            }
            else
            {
                RequestError *error = nil;
                
                if ([(NSString *)[dict objectForKey:@"errorCode"] length]) {
                    error = [RequestError initWithCode:[dict objectForKey:@"errorCode"] andErrorMsg:[dict objectForKey:@"errorMsg"]];
                }
                else
                {
                    error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                }
                
                success(nil, NO, error);
            }
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"-- %@", error.description);
        RequestError *errorMsg = [RequestError initWithCode:[NSString stringWithFormat:@"%@",[NSNumber numberWithInteger:error.code]] andErrorMsg:kFailMessage];
        if(error.code == NSURLErrorCancelled)
        {
            return;
        }else{
            fail(errorMsg);
        }
    }];
    
    return dataTask;
}




/**
 *   通过get方法获取数据
 *
 *  @param urlScheme        请求数据的接口
 *  @param paramsDict       请求参数的NSDictionary
 *  @param interfaceVersion 接口版本号
 *  @param success          请求数据成功的回调block
 *  @param fail             请求数据失败的回调block
 *
 *  @return  任务
 */
- (NSURLSessionDataTask *)getDataFromURLScheme:(NSString *)urlScheme
                              paramsDictionary:(id)paramsDict
                              interfaceVersion:(NSString *)interfaceVersion
                                       success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                                          fail:(void (^)(RequestError *errMsg))fail
{
    
    NSURLSessionDataTask *dataTask = [self getDataFromURLScheme:urlScheme paramsDictionary:paramsDict interfaceVersion:interfaceVersion contentType:nil success:success fail:fail];
    
    return dataTask;
}


/**
 @brief 通过get方式请求数据
 @param urlScheme 请求数据的接口
 @param paramsDict 请求参数的NSDictionary
 @param interfaceVersion 接口版本号
 @param contentType 接口版本号
 @param success 请求数据成功的回调block
 @param fail 请求数据失败的回调block
 */
- (NSURLSessionDataTask *)getDataFromURLScheme:(NSString *)urlScheme
                               paramsDictionary:(id)paramsDict
                               interfaceVersion:(NSString *)interfaceVersion
                                    contentType:(NSString *)contentType
                                        success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                                           fail:(void (^)(RequestError *errMsg))fail
{
    
    if (interfaceVersion.length)
    {
        urlScheme = [NSString stringWithFormat:@"/api/%@%@",interfaceVersion,urlScheme];
    }
    else
    {
//        if ([urlScheme rangeOfString:kDAQUrl].location == NSNotFound) {
//            urlScheme = [@"/api" stringByAppendingString:urlScheme];
//        }
    }
    
    [self addHttpRequestHeader:contentType rawData:NO params:paramsDict];
    
    NSURLSessionDataTask *dataTask = [_manager GET:urlScheme parameters:paramsDict progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if ([responseObject isKindOfClass:[NSDictionary class]]) {
            
            NSDictionary *dict = (NSDictionary *)responseObject;
            NSString *isSuccess = [NSString stringWithFormat:@"%@",[dict objectForKey:@"executeStatus"]];
            
            if ([isSuccess isEqualToString:@"0"]) {
                
                RequestError *error = [RequestError initWithCode:isSuccess andErrorMsg:kSuccessMessage];
                success([dict objectForKey:@"values"], YES, error);
            }
            else if ([isSuccess isEqualToString:@"3"] || [isSuccess isEqualToString:@"4"])
            {
                RequestError *error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                
                success(nil, NO, error);
                /*
                NSURLSessionDataTask *dataTask = [[UserManager getInstance] logout];
                
                if (dataTask) {
                    [SVProgressHUD showErrorWithStatus:[isSuccess isEqualToString:@"3"]?@"登录失效，请重新登录！":@"用户账号已删除！" duration:2.0];
                }*/
            }
            else if ([isSuccess isEqualToString:@"10"] || [isSuccess isEqualToString:@"11"])
            {
                RequestError *error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                
                success(nil, NO, error);
                /*
                [SVProgressHUD showErrorWithStatus:[isSuccess isEqualToString:@"10"]?@"缺少签名字段":@"签名错误" duration:2.0];*/
            }
            else
            {
                RequestError *error = nil;
                
                if ([(NSString *)[dict objectForKey:@"errorCode"] length]) {
                    error = [RequestError initWithCode:[dict objectForKey:@"errorCode"] andErrorMsg:[dict objectForKey:@"errorMsg"]];
                }
                else
                {
                    error = [RequestError initWithCode:@"-1" andErrorMsg:kFailMessage];
                }
                
                success(nil, NO, error);
            }
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"-- %@", error.description);
        RequestError *errorMsg = [RequestError initWithCode:[NSString stringWithFormat:@"%@",[NSNumber numberWithInteger:error.code]] andErrorMsg:kFailMessage];
        if(error.code == NSURLErrorCancelled)
        {
            return;
        }else{
            fail(errorMsg);
        }
    }];
    
    return dataTask;

}


/*
 @brief 下载文件、图片、视频
 @param urlScheme 请求数据的接口
 @param paramsDict 请求参数的NSDictionary
 @param success 请求数据成功的回调block
 @param fail 请求数据失败的回调block
 */
- (NSURLSessionDownloadTask *)downLoadFromURLScheme:(NSString *)urlScheme
                              paramsDictionary:(id)paramsDict
                                       success:(void (^)(id data, BOOL isSuccess, RequestError *msg))success
                                          fail:(void (^)(RequestError *errMsg))fail
{
    NSURL *URL = [NSURL URLWithString:urlScheme relativeToURL:_manager.baseURL];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
    request.timeoutInterval = kRequestTimeout*8;
    
    NSURLSessionDownloadTask *downloadTask = [_manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        
        NSLog(@"File downloaded to: %@", filePath);
        
        if (!error) {
            NSData *data = [NSData dataWithContentsOfURL:filePath];
            
            RequestError *error = [RequestError initWithCode:@"0" andErrorMsg:kSuccessMessage];
            success(data, YES, error);
        }
        else
        {
            NSLog(@"-- %@", error.description);
            RequestError *errorMsg = [RequestError initWithCode:[NSString stringWithFormat:@"%@",[NSNumber numberWithInteger:error.code]] andErrorMsg:kFailMessage];
            
            if(error.code == NSURLErrorCancelled)
            {
                return;
            }else{
                fail(errorMsg);
            }
        }
        
    }];
    
    [downloadTask resume];
    
    return downloadTask;
}


/**
 @brief 设置http response 响应信息
 @param rawData 直接接收服务端返回格式数据
 */
- (void)setHttpResponse:(BOOL)rawData
{
    if (rawData) {
        _manager.responseSerializer = [AFJSONResponseSerializer serializer];
    }
    else
        _manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
    
    _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",@"audio/amr",@"image/jpeg",nil];

}


/**
 @brief 设置http请求超时时间
 @param timeout 超时时间（单位：秒）
 */
- (void)setHttpRequestTimeout:(double)timeout
{
   _manager.requestSerializer.timeoutInterval = timeout;
}

/**
 @brief 增加http请求头部信息类型
 @param rawData 直接接收服务端返回格式数据
 @param contentType 请求数据类型
 @param params 请求参数
 */
- (void)addHttpRequestHeader:(NSString *)contentType rawData:(BOOL)rawData params:(id)params
{
   /* NSString *token  =[UserManager getInstance].user.token;
    
    if (token.length > 0)
    {
        [_manager.requestSerializer setValue:token forHTTPHeaderField:@"access-token"];
        
        if (params)
        {
            NSMutableDictionary *nParams = nil;
            
            if ([params isKindOfClass:[NSString class]]) {
                
                nParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:params,@"json",nil];
            }
            else if ([params isKindOfClass:[NSDictionary class]])
            {
                nParams = [NSMutableDictionary dictionaryWithDictionary:params];
            }
            
            if (nParams.allKeys.count) {
                
                NSString *timeStamp = [Util getCurrentTimeInterval];
                
                [nParams setObject:timeStamp forKey:@"ddtimestamp"];
                NSString *sign = [self crateDataSigner:nParams token:token];
                
                [_manager.requestSerializer setValue:timeStamp forHTTPHeaderField:@"ddtimestamp"];
                [_manager.requestSerializer setValue:sign forHTTPHeaderField:@"sign"];
                
                //            [_manager.requestSerializer setValue:@"MD5" forHTTPHeaderField:@"sign_type"];
            }
        }
    }
     */
    
    if (contentType) {
        [_manager.requestSerializer setValue:contentType forHTTPHeaderField:@"content-type"];
    }
    else
        [_manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
    
    [self setHttpResponse:rawData];
        _manager.requestSerializer.timeoutInterval = kRequestTimeout;
}

/**
 @brief 设置SSL安全策略
 */
+ (AFSecurityPolicy*)customSecurityPolicy
{
//    // /先导入证书
//    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ddhl" ofType:@"cer"];//证书的路径
//    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
    // AFSSLPinningModeCertificate 使用证书验证模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    
    // allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO
    // 如果是需要验证自建证书，需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;
    
    //validatesDomainName 是否需要验证域名，默认为YES；
    //假如证书的域名与你请求的域名不一致，需把该项设置为NO；如设成NO的话，即服务器使用其他可信任机构颁发的证书，也可以建立连接，这个非常危险，建议打开。
    //置为NO，主要用于这种情况：客户端请求的是子域名，而证书上的是另外一个域名。因为SSL证书上的域名是独立的，假如证书上注册的域名是www.google.com，那么mail.google.com是无法验证通过的；当然，有钱可以注册通配符的域名*.google.com，但这个还是比较贵的。
    //如置为NO，建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;
//    NSSet *set = [[NSSet alloc] initWithObjects:certData, nil];
//    securityPolicy.pinnedCertificates = set;
    
    return securityPolicy;
}



/**
 @brief 取消http请求
 */
- (void)cancelRequest
{
    [_manager.operationQueue cancelAllOperations];
    for (NSOperation *op in _manager.operationQueue.operations) {
        [op cancel];
    }
    
    for (NSURLSessionDataTask *dataTask in _manager.dataTasks) {
        if (dataTask.state == NSURLSessionTaskStateRunning || dataTask.state == NSURLSessionTaskStateSuspended) {
            [dataTask cancel];
        }
    }
}


@end
